//
//  AFNetworkTool.m
//  AFNetText2.5
//
//  Created by wxxu on 15/1/27.
//  Copyright (c) 2015年 wxxu. All rights reserved.
//

#import "AFNetworkTool.h"
#import <CommonCrypto/CommonDigest.h>
#import "Reachability.h"


@implementation AFNetworkTool

#pragma mark 检测网路状态
+ (BOOL)netWorkStatus
{
    /**
     AFNetworkReachabilityStatusUnknown          = -1,  // 未知
     AFNetworkReachabilityStatusNotReachable     = 0,   // 无连接
     AFNetworkReachabilityStatusReachableViaWWAN = 1,   // 3G 花钱
     AFNetworkReachabilityStatusReachableViaWiFi = 2,   // WiFi
     */
    
    // 如果要检测网络状态的变化,必须用检测管理器的单例的startMonitoring
    [[AFNetworkReachabilityManager sharedManager] startMonitoring];
    
    // 检测网络连接的单例,网络变化时的回调方法
    [[AFNetworkReachabilityManager sharedManager] setReachabilityStatusChangeBlock:^(AFNetworkReachabilityStatus status) {
        if (status == -1 || status == 0) {
            UIAlertView *bAlert = [[UIAlertView alloc] initWithTitle:@"小胖兔提示您" message:@"无法连接网络，请检查" delegate:self cancelButtonTitle:@"确定" otherButtonTitles:nil];
            [bAlert show];
        }
     }];
    // 引用Reachability.h 判断当前网络状态
    
    Reachability *reach = [Reachability reachabilityWithHostName:@"http://www.baidu.com"];
    NetworkStatus status = [reach currentReachabilityStatus];
    switch (status) {
        case NotReachable:
        {
            return NO;
        }
            break;
        case ReachableViaWiFi:
        {
            return YES;
        }
            break;
        case ReachableViaWWAN:
        {
            return YES;
        }
            break;
        default:
            break;
    }
    
}



#pragma mark - JSON方式获取数据
+ (void)JSONDataWithUrl:(NSString *)urlStr parameter:(NSDictionary *)dict success:(void (^)(id json))success fail:(void (^)())fail
{
    BOOL judge = [AFNetworkTool netWorkStatus];
    NSString *nameStr = [AFNetworkTool urlWithName:urlStr parameter:dict];
    AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];

    // 有网
    if (judge) {

        // 网络访问是异步的,回调是主线程的,因此程序员不用管在主线程更新UI的事情
        
        [manager GET:urlStr parameters:dict success:^(AFHTTPRequestOperation *operation, id responseObject) {
            if (success) {
                // 设置返回的数据仅为data
                manager.responseSerializer = [AFHTTPResponseSerializer serializer];
                // data 数据简单存入本地
                [AFNetworkTool writeWithName:nameStr data:responseObject directory:NSLibraryDirectory];
                id json = [NSJSONSerialization JSONObjectWithData:responseObject options:NSJSONReadingMutableContainers error:nil];
                // 解析后的数据回调到主线程
                success(json);

            }
        } failure:^(AFHTTPRequestOperation *operation, NSError *error) {
            NSLog(@"%@", error);
            if (fail) {
                fail();
                UIAlertView *aAlert = [[UIAlertView alloc] initWithTitle:@"小胖兔提示您" message:@"没有数据，请刷新界面" delegate:self cancelButtonTitle:@"确定" otherButtonTitles:nil];
                [aAlert show];

                
            }
        }];
    } else{// 没有网络
        // 判断本地存储中是否有存有数据的文件夹
        NSFileManager *fileManager = [NSFileManager defaultManager];
        NSString *naStr = [AFNetworkTool cachedFileNameForKey:nameStr];
        NSString *path = [AFNetworkTool pathWithName:naStr directory:NSLibraryDirectory];

        if ([fileManager fileExistsAtPath:path]) {
            //本地存储中有存有数据的文件夹，将data数据json解析
            id json = [AFNetworkTool readWithName:nameStr directory:NSLibraryDirectory];
            if (json) {
                // 回调到主线程
                success(json);
            }

        }

    }
}

#pragma mark - xml方式获取数据
+ (void)XMLDataWithUrl:(NSString *)urlStr parameter:(NSDictionary *)dict success:(void (^)(id xml))success fail:(void (^)())fail
{
    AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
    
    // 返回的数据格式是XML
    manager.responseSerializer = [AFXMLParserResponseSerializer serializer];
    
    
    // 网络访问是异步的,回调是主线程的,因此程序员不用管在主线程更新UI的事情
    [manager GET:urlStr parameters:dict success:^(AFHTTPRequestOperation *operation, id responseObject) {
        if (success) {
            success(responseObject);
        }
        
    } failure:^(AFHTTPRequestOperation *operation, NSError *error) {
        NSLog(@"%@", error);
        if (fail) {
            fail();
        }
    }];
}

#pragma mark - JSON方式post提交数据
+ (void)postJSONWithUrl:(NSString *)urlStr parameters:(id)parameters success:(void (^)(id responseObject))success fail:(void (^)())fail
{
    AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
    // 设置请求格式
    manager.requestSerializer = [AFJSONRequestSerializer serializer];
    // 设置返回格式
    manager.responseSerializer = [AFHTTPResponseSerializer serializer];
    [manager POST:urlStr parameters:parameters success:^(AFHTTPRequestOperation *operation, id responseObject) {
//        NSString *result = [[NSString alloc] initWithData:responseObject encoding:NSUTF8StringEncoding];
        if (success) {
            success(responseObject);
        }
    } failure:^(AFHTTPRequestOperation *operation, NSError *error) {
        NSLog(@"%@", error);
        if (fail) {
            fail();
        }
    }];
    
}


#pragma mark - Session 下载下载文件
+ (void)sessionDownloadWithUrl:(NSString *)urlStr success:(void (^)(NSURL *fileURL))success fail:(void (^)())fail
{
    NSURLSessionConfiguration *config = [NSURLSessionConfiguration defaultSessionConfiguration];
    AFURLSessionManager *manager = [[AFURLSessionManager alloc] initWithSessionConfiguration:config];

    NSString *urlString = [urlStr stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
    
    NSURL *url = [NSURL URLWithString:urlString];
    NSURLRequest *request = [NSURLRequest requestWithURL:url];
    
    NSURLSessionDownloadTask *task = [manager downloadTaskWithRequest:request progress:nil destination:^NSURL *(NSURL *targetPath, NSURLResponse *response) {
        // 指定下载文件保存的路径
        //        NSLog(@"%@ %@", targetPath, response.suggestedFilename);
        // 将下载文件保存在缓存路径中
        NSString *cacheDir = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES)[0];
        NSString *path = [cacheDir stringByAppendingPathComponent:response.suggestedFilename];
        
        // URLWithString返回的是网络的URL,如果使用本地URL,需要注意
//        NSURL *fileURL1 = [NSURL URLWithString:path];
        NSURL *fileURL = [NSURL fileURLWithPath:path];
        
//        NSLog(@"== %@ |||| %@", fileURL1, fileURL);
        if (success) {
            success(fileURL);
        }
        
        return fileURL;
    } completionHandler:^(NSURLResponse *response, NSURL *filePath, NSError *error) {
        NSLog(@"%@ %@", filePath, error);
        if (fail) {
            fail();
        }
    }];
    
    [task resume];
}


#pragma mark - 文件上传 自己定义文件名
+ (void)postUploadWithUrl:(NSString *)urlStr fileUrl:(NSURL *)fileURL fileName:(NSString *)fileName fileType:(NSString *)fileTye success:(void (^)(id responseObject))success fail:(void (^)())fail
{
    // 本地上传给服务器时,没有确定的URL,不好用MD5的方式处理
    AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
    manager.responseSerializer = [AFHTTPResponseSerializer serializer];
    //@"http://localhost/demo/upload.php"
    [manager POST:urlStr parameters:nil constructingBodyWithBlock:^(id<AFMultipartFormData> formData) {
        
//        NSURL *fileURL = [[NSBundle mainBundle] URLForResource:@"头像1.png" withExtension:nil];
        
        // 要上传保存在服务器中的名称
        // 使用时间来作为文件名 2014-04-30 14:20:57.png
        // 让不同的用户信息,保存在不同目录中
//        NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
//        // 设置日期格式
//        formatter.dateFormat = @"yyyy-MM-dd HH:mm:ss";
//        NSString *fileName = [formatter stringFromDate:[NSDate date]];
        
        //@"image/png"
        [formData appendPartWithFileURL:fileURL name:@"uploadFile" fileName:fileName mimeType:fileTye error:NULL];
        
    } success:^(AFHTTPRequestOperation *operation, id responseObject) {
        if (success) {
            success(responseObject);
        }
    } failure:^(AFHTTPRequestOperation *operation, NSError *error) {
        if (fail) {
            fail();
        }
    }];
}

#pragma mark - POST上传文件
+ (void)postUploadWithUrl:(NSString *)urlStr fileUrl:(NSURL *)fileURL success:(void (^)(id responseObject))success fail:(void (^)())fail
{
    AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
    // AFHTTPResponseSerializer就是正常的HTTP请求响应结果:NSData
    // 当请求的返回数据不是JSON,XML,PList,UIImage之外,使用AFHTTPResponseSerializer
    // 例如返回一个html,text...
    //
    // 实际上就是AFN没有对响应数据做任何处理的情况
    manager.responseSerializer = [AFHTTPResponseSerializer serializer];
    
    // formData是遵守了AFMultipartFormData的对象
    [manager POST:urlStr parameters:nil constructingBodyWithBlock:^(id<AFMultipartFormData> formData) {
        
        // 将本地的文件上传至服务器
//        NSURL *fileURL = [[NSBundle mainBundle] URLForResource:@"头像1.png" withExtension:nil];
        
        [formData appendPartWithFileURL:fileURL name:@"uploadFile" error:NULL];
    } success:^(AFHTTPRequestOperation *operation, id responseObject) {
//        NSString *result = [[NSString alloc] initWithData:responseObject encoding:NSUTF8StringEncoding];
//        
//        NSLog(@"完成 %@", result);
        if (success) {
            success(responseObject);
        }
    } failure:^(AFHTTPRequestOperation *operation, NSError *error) {
        NSLog(@"错误 %@", error.localizedDescription);
        if (fail) {
            fail();
        }
    }];
}

#pragma mark -
#pragma mark 拼接网址和参数
+ (NSString *)urlWithName:(NSString *)urlStr parameter:(NSDictionary *)parameter
{
    NSString *par = @"";
    for (NSString *key in [parameter allKeys]) {
        if ([par length] == 0) {
            par = [NSString stringWithFormat:@"?%@=%@", key, [parameter objectForKey:key]];
        } else {
            par = [NSString stringWithFormat:@"%@&%@=%@", par, key, [parameter objectForKey:key]];
        }
    }
    urlStr = [NSString stringWithFormat:@"%@%@", urlStr, par];
    return urlStr;
}

#pragma mark -
#pragma mark 读写本地数据库
+ (NSString *)pathWithName:(NSString *)name directory:(NSSearchPathDirectory)directory
{
    NSString *path = [NSSearchPathForDirectoriesInDomains(directory, NSUserDomainMask, YES) lastObject];
    path = [NSString stringWithFormat:@"%@/LocalityMemory", path];
    
    NSFileManager *manager = [NSFileManager defaultManager];
    if (![manager fileExistsAtPath:path]) {
        [manager createDirectoryAtPath:path withIntermediateDirectories:YES attributes:nil error:nil];
    }
    
    path = [NSString stringWithFormat:@"%@/%@", path, name];
    return path;
}

+ (void)writeWithName:(NSString *)name data:(NSData *)data directory:(NSSearchPathDirectory)directory
{
    name = [AFNetworkTool cachedFileNameForKey:name];
    NSString *path = [AFNetworkTool pathWithName:name directory:directory];
    [data writeToFile:path atomically:YES];
}

+(id)readWithName:(NSString *)name directory:(NSSearchPathDirectory)directory
{
    name = [AFNetworkTool cachedFileNameForKey:name];
    
    NSString *path = [AFNetworkTool pathWithName:name directory:directory];
    
    
    NSData *data = [NSData dataWithContentsOfFile:path];
    id json = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:nil];
    if (json) {
        return json;
    }
    return nil;
}



+ (NSString *)cachedFileNameForKey:(NSString *)key {
    const char *str = [key UTF8String];
    if (str == NULL) {
        str = "";
    }
    unsigned char r[CC_MD5_DIGEST_LENGTH];
    CC_MD5(str, (CC_LONG)strlen(str), r);
    NSString *filename = [NSString stringWithFormat:@"%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x",
                          r[0], r[1], r[2], r[3], r[4], r[5], r[6], r[7], r[8], r[9], r[10], r[11], r[12], r[13], r[14], r[15]];
    
    return filename;
}




@end
